/*
 * Copyright (c) 2022 Huawei Technologies Co.,Ltd.
 *
 * openGauss is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 * http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 * -------------------------------------------------------------------------
 *
 * cm_uuid.h
 *
 *
 * IDENTIFICATION
 * src/storage/gstor/zekernel/common/cm_uuid.h
 *
 * -------------------------------------------------------------------------
 */
#ifndef __CM_UUID_H__
#define __CM_UUID_H__
#include "cm_defs.h"
#include <stdio.h>
#include <string.h>

#ifdef _WIN32
#include <winsock2.h>
#include <nb30.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "NetAPI32.Lib")
#else
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#endif

typedef struct st_uuid_t {
    unsigned int Data1;     // Store the lower time 32 bits of 44 bits accurate to the millisecond level
    unsigned short Data2;   // Store the higher time 12 bits of 44 bits and 4 bits of the higher self-increasing seq
    unsigned short Data3;   // Store the lower 16 bits of the self-increasing seq
    unsigned char Data4[8]; // The first two array elements store the thread_id, the last 6 bytes store MAC Address
} uuid_t;

#define UUID_LEN 36
#define CM_GUID_LENGTH sizeof(uuid_t)
#define CM_THREAD_ID_LENGTH 2
#define CM_GUID_LAST_LENGTH (CM_GUID_LENGTH - GS_MAC_ADDRESS_LEN - CM_THREAD_ID_LENGTH)

#ifdef __cplusplus
extern "C" {
#endif

void cm_init_mac_address(char *mac_address, uint16 max_len);

/*
Definition: Generate global unique identifier
Input_param:
mac_address: MAC Address
uuid_increase: self-increasing sequence value, incrementing by one each time
thread_id: the current thread ID
Output_param:
uuid: Standard UUID structure
Return value:
0:   success
-1:  failed
Description: Generate global unique identifier
Algorithm logic:
UUID consists of five segments
1. Get timestamps accurate to the millisecond level, taking 44-bit to support more than 500 years,
   the lower 32-bit of time are stored in uuid.DATA1
2. The higher 12-bit of the timestamp are stored in the first 12-bit of uuid.DATA2, and the last 4-bit
   store the upper 4-bit of the self-increasing sequence.
3. uuid.DATA3 store the lower 16-bit of the self-increasing seq, So its scope is 0~1048575.
   The initial value of the self-incrementing sequence is generated by the thread id of SHA hash.
4. Get the current thread ID, take the lower 16-bit store in the first two array elements of uuid.DATA4.
5. Get the MAC address of the network card store in the last 48-bit of uuid.DATA4.
   If there are multiple network cards, only take one. If the acquisition fails, take a 48-bit random number.
*/
#ifdef __cplusplus
}
#endif

#endif
